package cn.tedu.forum.resource.controller;

import cn.tedu.forum.commons.exception.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static cn.tedu.forum.commons.response.ServiceCode.*;

@RestController
@RequestMapping("/upload")
public class FileUploadController {
    /**
     * 在application-dev.yml文件中配置上传文件的根目录，然后在此类中引用
     */
    @Value("${csmall.file-upload.base-dir}")
    private String baseDir;

    @PostMapping("/avatar")
    public String uploadAvatar(MultipartFile file) throws Throwable {
        String targetParentDirName = "Avatar";
        String targetSubDirName = generateDirNameByDate();
        List<String> contentTypes = new ArrayList<>();
        contentTypes.add("image/png");
        contentTypes.add("image/jpg");
        contentTypes.add("image/jpeg");
        long maxSize = 20 * 1024 * 1024;
        upload(file, maxSize, contentTypes, targetParentDirName, targetSubDirName);
        return "OK";
    }

    /*@PostMapping("/brand-icon")
    public String uploadBrandIcon(MultipartFile file, String brandPinyin) throws Throwable {
        String targetParentDirName = "BrandIcon";
        List<String> contentTypes = new ArrayList<>();
        contentTypes.add("image/png");
        contentTypes.add("image/jpg");
        contentTypes.add("image/jpeg");
        long maxSize = 100 * 1024;
        upload(file, maxSize, contentTypes, targetParentDirName, brandPinyin);
        return "OK";
    }*/

    private void upload(MultipartFile file, long maxSize, List<String> contentTypes,
                        String targetParentDirName, String targetSubDirName) throws Throwable {
        // 判断是否存在上传数据
        if (file == null || file.isEmpty()) {
            throw new ServiceException(NOT_ACCEPTABLE, "上传失败，请选择正确的文件再提交！");
        }
        // 判断文件大小是否超出了限制
        if (file.getSize() > maxSize) {
            throw new ServiceException(NOT_ACCEPTABLE,
                    "上传失败，文件大小超出了限制（最大" + maxSize / 1024 / 1024 + "MB）！");
        }
        // 判断文件MIME类型，例如：image/jpeg
        String contentType = file.getContentType();
        if (!contentTypes.contains(contentType)) {
            throw new ServiceException(NOT_ACCEPTABLE,
                    "上传失败，不允许使用" + contentType + "类型的文件，允许的文件类型有：" + contentTypes);
        }

        // 上传的文件夹
        String baseDir = "D:/CSMallServerPictures/";
        File targetParentDir = new File(baseDir, targetParentDirName);
        File targetSubDir = new File(targetParentDir, targetSubDirName);
        if (!targetSubDir.exists()) targetSubDir.mkdirs();

        // 上传的文件名
        String filename = generateFileNameByTime() + "-" + System.nanoTime() + "-" + getRandomValue();
        // 上传的扩展名
        String originalFilename = file.getOriginalFilename();
        int i = originalFilename.lastIndexOf(".");
        String suffix = originalFilename.substring(i);
        // 上传的文件的全名
        String fileFullName = filename + suffix;

        File dest = new File(targetSubDir, fileFullName);
        file.transferTo(dest);

    }

    /**
     * 用于格式化日期的工具对象
     */
    private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");

    /**
     * 根据日期生成文件夹名称
     *
     * @return 当前日期对应的文件夹名称
     */
    private String generateDirNameByDate() {
        LocalDateTime now = LocalDateTime.now();
        return dateFormatter.format(now);
    }

    private String generateFileNameByTime() {
        LocalDateTime now = LocalDateTime.now();
        return dateTimeFormatter.format(now);
    }

    private Random random = new Random();

    private int getRandomValue() {
        return random.nextInt(900000) + 100000;
    }
}
